package org.road0329.dlt698.axdr;

import org.road0329.dlt698.ReverseByteArrayInputStream;
import org.road0329.dlt698.ReverseByteArrayOutputStream;
import org.road0329.dlt698.asn1.axdr.AxdrType;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class DateTime extends AxdrType {
    private byte[] dataCode = null;
    private Unsigned16 year = null;
    private Unsigned8 month = null;
    private Unsigned8 dayOfMonth = null;
    private Unsigned8 dayOfWeek = null;
    private Unsigned8 hour = null;
    private Unsigned8 minute = null;
    private Unsigned8 second = null;
    private Unsigned8 milliseconds = null;

    public DateTime() {
    }

    public byte[] getDataCode() {
        return dataCode;
    }

    public void setDataCode(byte[] dataCode) {
        this.dataCode = dataCode;
    }

    public void setDateTime(Unsigned16 year, Unsigned8 month, Unsigned8 dayOfMonth,
                            Unsigned8 dayOfWeek, Unsigned8 hour, Unsigned8 minute,
                            Unsigned8 second, Unsigned8 milliseconds) {
        this.year = year;
        this.month = month;
        this.dayOfMonth = dayOfMonth;
        this.dayOfWeek = dayOfWeek;
        this.hour = hour;
        this.minute = minute;
        this.second = second;
        this.milliseconds = milliseconds;
    }

    public int decode(ReverseByteArrayInputStream input) throws Exception {
        int codeLength = 0;
        this.year = new Unsigned16();
        this.year.setConst();
        codeLength += this.year.decode(input);
        this.month = new Unsigned8();
        this.month.setConst();
        codeLength += this.month.decode(input);
        this.dayOfMonth = new Unsigned8();
        this.dayOfMonth.setConst();
        codeLength += this.dayOfMonth.decode(input);
        this.dayOfWeek = new Unsigned8();
        this.dayOfWeek.setConst();
        codeLength += this.dayOfWeek.decode(input);
        this.hour = new Unsigned8();
        this.hour.setConst();
        codeLength += this.hour.decode(input);
        this.minute = new Unsigned8();
        this.minute.setConst();
        codeLength += this.minute.decode(input);
        this.second = new Unsigned8();
        this.second.setConst();
        codeLength += this.second.decode(input);
        this.milliseconds = new Unsigned8();
        this.milliseconds.setConst();
        codeLength += this.milliseconds.decode(input);
        return codeLength;
    }

    public int encode(ReverseByteArrayOutputStream output) throws Exception {
        int codeLength;
        if (this.dataCode != null) {
            codeLength = this.dataCode.length;
            for (int i = this.dataCode.length - 1; i >= 0; i--) {
                output.write(this.dataCode[i]);
            }
        } else {
            if (this.year != null && this.month != null && this.dayOfWeek != null
                    && this.dayOfMonth != null && this.hour != null && this.minute != null
                    && this.second != null) {
                codeLength = 0;
                codeLength += this.milliseconds.encode(output);
                codeLength += this.second.encode(output);
                codeLength += this.minute.encode(output);
                codeLength += this.hour.encode(output);
                codeLength += this.dayOfWeek.encode(output);
                codeLength += this.dayOfMonth.encode(output);
                codeLength += this.month.encode(output);
                codeLength += this.year.encode(output);
            } else {
                throw new RuntimeException("DateTime is null");
            }
        }
        return codeLength;
    }

    public void encodeAndSave(int encodingSizeGuess) throws Exception {
        ReverseByteArrayOutputStream revOStream = new ReverseByteArrayOutputStream();
        revOStream.setBufSize(encodingSizeGuess);
        this.encode(revOStream);
        this.dataCode = revOStream.getArray();
    }

    @Override
    public String toString() {
        if (this.year != null && this.month != null && this.dayOfMonth != null
                && this.dayOfWeek != null && this.hour != null && this.minute != null
                && this.second != null) {
            return "sequence: {" + "year: " + this.year + ", month: " + this.month + ", dayOfMonth: " + this.dayOfMonth
                    + ", dayOfWeek" + this.dayOfWeek + ", hour: " + this.hour + ", minute: " + this.minute + ", second: " + this.second + "}";
        } else {
            return "DateTime is null";
        }
    }
}



